package de.fhd.pms.dao;

import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import de.fhd.pms.dto.FahrtTeilnehmerDTO;
import de.fhd.pms.model.Automobil;
import de.fhd.pms.model.Fahrt;
import de.fhd.pms.model.Teilnehmer;

/*
 * Schritt 6.1: DAO-Klasse als Unterklasse von HiberneteDaoSupport deklarieren
 */

/**
 * Data-Access-Object (DTO) von Teilnehmer.
 * <p>
 * DTO wird verwendet, um Persistenz bzw. den Zugriff auf eine Datenbank zu
 * gewährleisten, ohne spezielle datenbankabhängigen Befehle.
 * 
 * @author Martin Schmid
 * @author Florian Schachner
 */
public class TeilnehmerDao extends HibernateDaoSupport {

	private static Logger log = Logger.getLogger(TeilnehmerDao.class);

	private FahrtDao fahrtDao;
	
	public void setFahrtDao(FahrtDao fahrtDao) {
		this.fahrtDao = fahrtDao;
	}
	
	
	
	/*
	 * Schritt 6.2: save-Methode deklarieren, der eine Teilnehmerinstanz als
	 * Parameter übergeben erhält
	 */

	/**
	 * Save-Methode von TeilnehmerDAO.
	 * <p>
	 * Hierbei wird eine Teilnehmerinstanz als Parameter an die Methode
	 * übergeben und gespeichert.
	 * 
	 * @param teilnehmer
	 *            - ein {@link Teilnehmer} wird in der Datenbank gespeichert
	 * @return teilnehmer
	 * @author Martin Schmid
	 * @author Florian Schachner
	 */
	public Teilnehmer save(Teilnehmer teilnehmer) {
		HibernateTemplate template = getHibernateTemplate();
		template.saveOrUpdate(teilnehmer);
		return teilnehmer;
	}

	/**
	 * FindById-Methode von TeilnehmerDAO.
	 * <p>
	 * Hierbei wird die Suche nach einer Teilnehmerinstanz anhand des
	 * Primärschlüssels ermöglicht.
	 * 
	 * @param id
	 *            - int, Primärschlüssel eines {@link Teilnehmer}
	 * @return Teilnehmer
	 * @author Martin Schmid
	 * @author Florian Schachner
	 */
	public Teilnehmer findById(int id) {
		HibernateTemplate template = getHibernateTemplate();
		return (Teilnehmer) template.get(Teilnehmer.class, id);
	}

	/**
	 * FindAll-Methode von TeilnehmerDAO.
	 * <p>
	 * Hierbei wird die Suche nach allen Teilnehmern ermöglicht.
	 * 
	 * @return results - eine Liste von Teilnehmer-Objekten
	 * @author Martin Schmid
	 * @author Florian Schachner
	 */
	@SuppressWarnings("unchecked")
	public List<Teilnehmer> findAll() {
		HibernateTemplate template = getHibernateTemplate();
		@SuppressWarnings("rawtypes")
		List results = template.loadAll(Teilnehmer.class);
		return results;
	}

	/**
	 * Delete-Methode von TeilnehmerDAO.
	 * <p>
	 * Hierbei wird das Löschen einer Teilnehmerinstanz ermöglicht.
	 * 
	 * @param teilnehmer
	 *            - {@link Teilnehmer} wird gelöscht
	 * @author Martin Schmid
	 * @author Florian Schachner
	 */
	public void delete(Teilnehmer teilnehmer) throws TeilnehmerDeleteException {
		log.info("TEILNEHMERDAO: delete()");
		HibernateTemplate template = getHibernateTemplate();
		
		Set<Fahrt> fahrtenVonTeilnehmer = fahrtDao.findByTeilnehmer(teilnehmer);
		
		if (fahrtenVonTeilnehmer.size() == 0){
			template.delete(teilnehmer);
		}
		else{
			throw new TeilnehmerDeleteException("Leider kann der Teilnehmer nicht aus dem Teilnehmerstamm entfernt werden, da der Teilnehmer bereits Fahrten absolviert hat.");
		}
	}

	/**
	 * FindFreie-Methode von TeilnehmerDAO.
	 * <p>
	 * Hierbei wird die Suche nach allen Teilnehmern ermöglicht, welche sich
	 * nicht gerade unterwegs befinden, sprich welche sich kein Automobil
	 * ausgeliehen haben. Diese Methode schränkt den Suchraum so also ein, dass
	 * nur Teilnehmer angezeigt werden, die momentan keine Fahrt absolvieren.
	 * 
	 * @return result
	 * @author Martin Schmid
	 * @author Florian Schachner
	 */
	@SuppressWarnings("unchecked")
	public List<Teilnehmer> findFreieMitFahrerlaubnis() {
		HibernateTemplate template = getHibernateTemplate();
		
		List<Teilnehmer> alleFreienMitFahrerlaubnis = template.find("from Teilnehmer t where t.available = 1 and t.fahrerlaubnis = 1");
		return alleFreienMitFahrerlaubnis;
		
		/*
		log.info("*** ALLE AKTUELL LAUFENDEN FAHRTEN ***");
		List<Fahrt> aktuelleFahrten = template.find("from Fahrt f where f.endefahrt is null");

		log.info("*** TEILNEHMER DIE AKTUELL UNTERWEGS SIND ***");
		List<Teilnehmer> mobileTeilnehmer = new LinkedList<Teilnehmer>();
		for (Fahrt fahrt : aktuelleFahrten) {
			log.info("NEU MOBILER: " + fahrt.getTeilnehmer().getId());
			mobileTeilnehmer.add(fahrt.getTeilnehmer());
		}

		log.info("*** ALLE TEILNEHMER IM CARSHARINGPROJEKT ***");
		List<Teilnehmer> alle = template.loadAll(Teilnehmer.class);

		log.info("*** AKTUELL VERFUEGBARE TEILNEHMER MIT FAHRERLAUBNIS***");
		// FUNKTIONIERT NOCH NICHT RICHTIG
		List<Teilnehmer> result = new LinkedList<Teilnehmer>();

		
		log.info("Anzahl mobiler Teilnehmer: " + mobileTeilnehmer.size());
		if (mobileTeilnehmer.size() != 0) {
			for (Teilnehmer teilnehmer : alle) {
				log.info("*********** CHECK TEILNEHMER ****************");
				log.info("** " + teilnehmer.getId());
				log.info("** " + teilnehmer.getNachname() + " " + teilnehmer.getVorname());
				log.info("** " + teilnehmer.getFahrerlaubnis());
				log.info("******************************************");
				
				
				if (teilnehmer.getFahrerlaubnis() == true){ //Teilnehmer ohne Fahrerlaubnis ausgeschlossen
				log.info("**** Fahrerlaubnis: " + teilnehmer.getFahrerlaubnis());

					
					
					for (Teilnehmer mobilerTeilnehmer : mobileTeilnehmer) {
						String a1 = "" + teilnehmer.getId();
						String a2 = "" + mobilerTeilnehmer.getId();

						//log.info("-----------------------");
						//log.info(a1 + "==" + a2 +"==>" + a1.compareTo(a2));
						//log.info(teilnehmer);
						//log.info(teilnehmer.getId() + " " + teilnehmer.getNachname() + " " + teilnehmer.getVorname());
						//log.info("-----------------------");

						
						if (a1.compareTo(a2)!=0){ //Wenn die ID des mobilen Teilnehmers nicht mit der ID des geprüften Teilnehmers übereinstimmt
							log.info("RESULT EMPTY: " + result.isEmpty());
							if (result.isEmpty()==true){
								result.add(teilnehmer);
							}
							else{
								int s=0;
								for (Teilnehmer tn : result) {
									String a3 = "" + tn.getId();
									if (a3==a1){
										log.info("a3==a2" + (a3==a1));
										s=s+1;
									}
								}
								
								if (s>0){
									result.add(teilnehmer);
								}
							}

						}
						
						
						
						//log.info("-----------------------");
						//log.info("Alle: " + teilnehmer.getId() + " " + teilnehmer.getNachname() + " " + teilnehmer.getVorname());
						//log.info("Mobiler: " + mobilerTeilnehmer.getId() + " " + mobilerTeilnehmer.getNachname() + " " + mobilerTeilnehmer.getVorname());
						//log.info(a1 + "==" + a2);
						//log.info("-----------------------");
					}
				}

			}
		} else { //Wenn keine offenen Fahrten bestehen, dann stehen alle Teilnehmer mit Fahrerlaubnis zur Verfügung
			for (Teilnehmer teilnehmer : alle) {
				if (teilnehmer.getFahrerlaubnis() == true) {
					result.add(teilnehmer);
				}
			}
		}
		
		*/
		
		
	}

}
